home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1994
/
MacHack 1994.toast
/
MacHack™94
/
Talks & Papers
/
Timothy Knox
/
yerk 3.66
/
System source
/
Ovl
< prev
next >
Wrap
Text File
|
1994-06-24
|
8KB
|
255 lines
\ Module - overlay support for Yerk modules
\ 11/19/84 CBD Version 1
\ 7/10/86 cdn rewrote reloc in code
\ 3/22/91 rfl prettied up (.mod)
\ 4/29/93 rfl when modules are loaded, search for 'proc' and set with a5,a3
\ 5/01/93 rfl removed n>count since defined in nuc
\ 5/29/93 rfl getPtrSize now takes relative pointer as input.
\ 5/31/93 rfl added Mike Hore's trav words
\ 1/05/94 rfl added keepMod...uses lock byte hi bit
\ 1/31/94 rfl added ?pause to (.mods) and keeplocked for use within modules
\ 2/09/94 rfl added purge! for sysinit. When program starts up, want
\ to purge all mods, even if locked (from the save)
Decimal
\ ( n -- 2^n )
: 2** 1 swap << ;
\ the bitMap class is an array of bits - allocation is #bytes
:CLASS bitMap <Super Object 1 <indexed \ for allocation only
\ ( ind -- byte ) return the byte at ind
:M BYTEAT: ?range at1 ;M
\ ( val ind -- ) store byte value at ind
:M BYTETO: ?range to1 ;M
\ ( ind -- 1 OR 0 ) get bit #ind
:M AT: abs 8 /mod byteAt: self swap 2** And 0= 0= ;M
\ ( 1 OR 0 ind -- ) store bit #ind
:M TO: { val ind \ bit# -- } ind abs 8 /mod -> ind -> bit#
ind byteAt: self bit# 2** Or ind byteTo: self ;M
:M SET: 1 swap To: self ;M
;CLASS
0 Value Bits \ will hold ptr to base of bitMap
'type BIN Constant binType \ file type for overlays
\ 6 constant parmsLen \ 0:1=len, 2:5=original addr
\ ( addr len offset bits -- ) code version of module relocate
Create reloc
$ 205f w, \ move.l (sp)+,a0 ; bits
$ 41f38804 , \ lea 4(a3,a0.l),a0
$ 201f w, \ move.l (sp)+,d0 ; offset (relocation factor)
$ 221f w, \ move.l (sp)+,d1 ; len
$ 225f w, \ move.l (sp)+,a1 ; base addr
$ 43f39800 , \ lea 0(a3,a1.l),a1
$ 4284 w, \ clr.l d4 ; init module relative position
$ 143c0001 , \ move.b #1,d2 ; init mask
$ 1c02 w, \ loop move.b d2,d6
$ cc3c0001 , \ and.b #1,d6 ; time to get new byte?
$ 6702 w, \ beq.s test ; no, still using same byte
$ 1618 w, \ move.b (a0)+,d3 ; get next "bits" byte
$ 1c03 w, \ test move.b d3,d6
$ cc02 w, \ and.b d2,d6 ; test this bit
$ 6704 w, \ beq.s nextb
$ d1b14800 , \ add.l d0,0(a1,d4.l) ; add reloc factor
$ e31a w, \ nextb rol.b #1,d2 ; shift mask
$ 5484 w, \ addq.l #2,d4 ; increment offset into module
$ 5381 w, \ subq.l #1,d1
$ 66e4 w, \ bne.s loop ; decrement len (bit map)
next,
\ ( ovLen -- bitmapLen ) Find bitmap length for overlay
: bitsLen abs 16 /mod 2* swap IF 2+ THEN 8+ ;
\ leave name of binary file for module
( addr len -- addr1 len1 )
: binName { addr len -- }
addr pad len cmove
" .BIN" pad len + swap cmove
pad len 4+ ;
\ ( nfa -- base ) load and relocate a binary module from it's data file
: loadBin { \ len bLen org base -- }
n>count binName name: fFcb
openReadOnly: fFcb ?error 138
size: fFcb 6 ( parmsLen ) - \ find parms
moveto: fFcb drop
pad 6 ( parmsLen ) read: fFcb ?error 141
0 moveTo: fFcb drop
pad w@ -> len pad 2+ @ -> org \ get parms
len ovBlock -> base \ get block for module code
base len read: fFcb ?error 141
len bitsLen -> bLen \ length of bitmap in bytes
bLen 4+ ovBlock 4+ -> bits \ heap for bitmap
bits 4- bLen read: fFcb ?error 141
close: fFcb drop
bits 4- @ ' bitmap <> ?error 142 \ sentinel
base len base org - bits reloc \ relocate the module
dispose> bits base ;
Handle mHndl
\ ( resID -- handle ) load and relocate a binary module from it's resource
: loadBinR { \ len org -- }
GetRes CODE -dup 0= ?error 138
dup put: mHndl \ leave copy of handle on the stack
ptr: mHndl size: mHndl + 6 -
dup w@ -> len 2+ @ -> org
ptr: mHndl len + 4+ -> bits
ptr: mHndl len over org - bits reloc
len setSize: mHndl \ dump bitMap
;
: ?mod @ modCode = ;
\ locking a module prevents the Yerk growZone routine from
\ purging it while it is executing.
\ ( cfa -- ) lock/unlock the module whose cfa is on stack
: mUnlock 12 + dup c@ $ 80 and swap c! ;
: mLock 12 + dup c@ $ 1 or swap c! ;
: ?mlock 12 + c@ $ 1 and 1 = ; \ true if module is locked
: ?keep 12 + c@ $ 80 and $ 80 = ;
: KeepLocked 1 swap 12 + @ $ ffffff and c! ; \ use within module to keep
\ it locked. In the case of an
\ open window or the like.
: installMod { b -- } @word count sfind
IF drop cfa dup ?mod not ?error 147
12 + dup c@ b IF $ 80 or ELSE $ 7f and THEN swap c!
ELSE type# 172
THEN ;
create getPtrSize popA0 $ d1cb w, $ a021 w, pushD0 next,
create recoverHndl popA0 $ a128 w, pushA0 next,
create geta3a5 ( -- a3 a5) $ 2f0b w, $ 2f0d w, next,
\ named input parm replace is true if handle,, false if ptr
: fixProcMod { ptr replace \ len myString addr -- ptr }
replace IF ptr +base recoverHndl getHSize
ELSE ptr getPtrSize
THEN -> len
0 -> replace
heap> string -> myString new: myString
ptr len put: myString
start: mystring
BEGIN " proc" indexof: myString
WHILE ptr: myString + 4+ -> addr
getA3A5 addr ! addr 4+ !
where: myString 4+ moveto: myString
true -> replace
REPEAT
replace IF get: myString ptr swap cmove THEN
release: myString dispose> myString
ptr ;
\ mcfa structure to define a module. This will reside in the
\ resident dictionary, being the link between resident words and
\ words in the module.
3 codeFields
\ ( addr -- ) Release the heap storage for the module
Do.. dup c@ 1 and 0= \ unlocked ?
IF dup @ $ 7fffffff and 0 <> \ unlocked and loaded?
IF dup 10 + w@
IF dup 12 + @ $ a9a3 Trap \ call ReleaseResource
ELSE dup @ $ 7fffffff and killPtr THEN
THEN dup @ $ 80000000 and swap !
ELSE drop
THEN
..End
\ ( offs addr -- ) execute the export vector at offset in module
Do.. dup 12 - >R \ save the address of the mod's cfa
R execute \ exec 0cfa to load the module
R mlock \ lock the module while it executes
@ $ FFFFFF and >R R + @ execute \ execute the import word
R> c@ IF R> drop \ leave module locked?
ELSE R> mUnlock THEN
..End
\ ( addr -- ) Load the module if not loaded
Do.. dup @ $ 7fffffff and 0=
IF dup 10 + w@ -dup \ load module and update pointer to base
IF loadBinR 2dup swap 12 + ! >ptr true \ resource based module
ELSE dup 12 - >name loadBin false \ file based module
THEN
fixProcMod \ search all :proc defs and fill w/a5,a3
over @ or swap !
ELSE drop
THEN
..End
\ module def data consists of |^moduleBase|^lastImport|#imports|resID|mHandle|
: modDef Build 0, 0, 0 w, 0 w, 0, ..End
false value endTrav? \ May be set from within a trav handler to terminate the trav
\ traverse the dictionary, applying passed-in proc to each cfa...start from nfa
: (trav) { theWord parm nfa -- }
false -> endTrav? nfa
BEGIN 1 traverse align dup 4+ parm exec> theWord
@ dup 0= endTrav? or
UNTIL drop ;
: trav latest (trav) ;
: travFrom ( nfa --) (trav) ;
\ handler to release selected modules
: ?disp { theCfa size -- }
theCfa ?mod \ if this is a module
IF free size < \ if we still need space
IF theCfa 8+ execute \ 2cfa is Dispose>
THEN
THEN ;
\ Release will free all unlocked modules on a small Mac,
\ and frees 150K bytes on a large Mac.
: release 'c ?disp 150000 trav ;
\ release if unlocked - don't unlock
: (purge) { theCfa size -- } theCfa ?mod
IF theCfa 4+ 8+ dup c@ $ 81 and swap c!
theCfa size ?disp
THEN ;
\ free all unlocked modules ( Forward reference in file: Base )
:F purge 'c (purge) 100000000 trav ;F
\ use during startup (sysinit)...any module marked as locked should be cleared
\ but keep install status
: (purge!) { theCfa size -- } theCfa ?mod
IF theCfa 4+ 8+ dup c@ $ 80 and swap c!
theCfa size ?disp
THEN ;
: purge! 'c (purge!) 100000000 trav ;
\ ( #bytes -- ) release modules until #bytes are available
: need freeblk . 'c ?disp swap trav ;
\ list existing modules and their load status
: (.mod) { theCfa size -- } curs -curs theCfa ?mod
IF ?pause cr theCfa >name id. @xy swap drop 90 swap gotoxy
theCfa 12 + @ $ ffffff and .h
theCfa ?mLock IF type# 174 ( ***Locked***) THEN
theCfa ?keep IF type# 168 ( ***Keep***) THEN
THEN -> curs ;
\ list modules and their load status
: .mods 'c (.mod) 0 trav ;